﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D; // For CompositingQuality

namespace RobotCleaner
{
    /// <summary>
    /// =========================
    ///    Class : Robot  
    ///    Date  : Sep 14th,2013
    ///    By    : EndlessRain
    /// =========================
    /// </summary>
    [Serializable] // 表示可序列化的
    public class Robot
    {
        private bool _bBackwardAhead = true;
        public bool bBackwardAhead
        {
            get { return _bBackwardAhead;}
            set { _bBackwardAhead = value;}
        }

        private int maxStepForBackwards = 20;
        public int MaxStepForBackwards
        {
            get { return maxStepForBackwards;}
        }
        /// <summary>
        /// 后退清扫的步长
        /// </summary>
        private int stepForBackwards = 0;
        public int StepForBackwards
        {
            get { return stepForBackwards; }
            set { stepForBackwards = value;}
        }
        /// <summary>
        /// 碰撞次数
        /// </summary>
        private int _CollideCount = 0; // 默认为0
        /// <summary>
        /// 碰撞次数
        /// </summary>
        public int CollideCount
        {
            get { return _CollideCount; }
            set { _CollideCount = value; }
        }

        /// <summary>
        /// 随机转过角度 整型数组
        /// </summary>
        //public int[] AnglesForStochastic = { 95,105,120};
        //public int[] AnglesForStochastic = { 100, 120, 130 };
        //public int[] AnglesForStochastic = { 95, 118, 70 };
        //public int[] AnglesForStochastic = { 95, 120, 70 };

        //public int[] AnglesForStochastic = { 165, 135, 105, 75, 45, 15 };
        //public int[] AnglesForStochastic = { 170, 140, 110, 80, 50, 20 };

        //public int[] AnglesForStochastic = { 150, 126, 102, 78, 54, 30 };
        //public int[] AnglesForStochastic = { 95, 105, 115, 125, 135, 145 };

        //public int[] AnglesForStochastic = { 91, 116, 116, 76, 76, 91 };

        //public int[] AnglesForStochastic = { 95, 121, 121, 61, 61, 95 };
        //public int[] AnglesForStochastic = { 96, 121, 61, 121, 61, 96 };

        //public int[] AnglesForStochastic = { 151, 121, 61, 61, 61, 105 };


        //public int[] AnglesForStochastic = { 151, 151, 91, 91, 31, 31 };

        //public int[] AnglesForStochastic = { 166, 121, 121, 61, 61, 16 };

        // Z
        //public int[] AnglesForStochastic = { 166, 121, 61, 121, 61, 16 };

        //public int[] AnglesForStochastic = { 39, 63, 87, 111, 135, 159 };
        public int[] AnglesForStochastic = { 159, 135, 111, 87, 63, 39 };

        /// <summary>
        /// 清扫分析类
        /// </summary>
        public CleanAnalyze Analyze;
        private bool hasDetectedDirty = false;
        /// <summary>
        /// 是否侦测到污浊区域
        /// </summary>
        public bool HasDetectedDirty
        {
            get { return hasDetectedDirty; }
            set { hasDetectedDirty = value; }
        }
        /// <summary>
        /// 累计环绕角度 
        /// </summary>
        private float anglesRound = 0;//Sep 26,2013
        /// <summary>
        /// 环绕圈数
        /// </summary>
        private int roundCount = 0;
        /// <summary>
        /// 累计环绕角度
        /// </summary>
        public float AnglesRound
        {
            get { return anglesRound; }
            set { anglesRound = value; }
        }
        /// <summary>
        /// 环绕圈数
        /// </summary>
        public int RountCount
        {
            get { return roundCount; }
            set { roundCount = value; }
        }
        /// <summary>
        /// 环绕数据初始化（角度，圈数等）清零
        /// </summary>
        public void initializeAngles() 
        {
            anglesRound = 0;
            roundCount = 0;
        }
        /// <summary>
        /// 沿墙完成
        /// </summary>
        private bool _CleanWallFinished = false;
        /// <summary>
        /// 沿墙完成
        /// </summary>
        public bool CleanWallFinished
        {
            get { return _CleanWallFinished; }
            set { _CleanWallFinished = value;}
        }
        /// <summary>
        /// 沿墙角度
        /// </summary>
        private int cleanWallAngle = 0;
        /// <summary>
        /// 沿墙角度
        /// </summary>
        public int CleanWallAngle
        {
            get { return cleanWallAngle; }
            set { cleanWallAngle = value; }
        }
        /// <summary>
        /// 沿墙角度清零
        /// </summary>
        public void clearClearWallAngle()
        {
            cleanWallAngle = 0;
        }
        /// <summary>
        /// 检查沿墙完成
        /// </summary>
        public void checkCleanWallFinished()
        { 
            
        }
        /// <summary>
        /// 下一个X坐标
        /// </summary>
        private int _R_Next_X;
        /// <summary>
        /// 下一个Y坐标
        /// </summary>
        private int _R_Next_Y;
        /// <summary>
        /// 下一个X坐标
        /// </summary>
        public int R_Next_X
        {
            get { return _R_Next_X;}
            set { _R_Next_X = value; }
        }
        /// <summary>
        /// 下一个Y坐标
        /// </summary>
        public int R_Next_Y
        {
            get { return _R_Next_Y; }
            set { _R_Next_Y = value; }
        }
        /// <summary>
        /// 5个传感器
        /// </summary>
        public Transducer[] t = new Transducer[5];
        /// <summary>
        /// 传感器角度
        /// </summary>
        //private int[] transducerAngles = { 10, 20, 30, 40, 50 };
        //private int[] transducerAngles = { 30, 30, 30, 30, 30 };
        private int[] transducerAngles = { -70, -40, 0, 40, 70 };
        /// <summary>
        /// 传感器测量距离
        /// </summary>
        private int transducerDistance = _R_Width / 2 + step ;
        /// <summary>
        /// 传感器测量距离
        /// </summary>
        public int TransducerDistance
        {
            get { return transducerDistance; }
            set { transducerDistance = value;}
        }
        //=========================================================================================================================
        /* 颜色设置 */
        //private Color path_color = Color.FromArgb(156, 170, 193); 
        private Color path_color = Color.Green;   // 机器人 轨迹颜色
        private Color center_color = Color.Red;  // 机器人 中心颜色
        //=========================================================================================================================
        /* 时间设置 */
        private int _R_Time = 1;             // 机器人 行走一个单位步长的 时间间隔
        //=========================================================================================================================
        /* 坐标设置 */ 
        //private int R_X = 100;                       // 机器人 初始 X坐标
        //private int R_Y = 100;                       // 机器人 初始 Y坐标
        //private int _R_Width = 40;                  // 机器人 宽度
        //private int _R_Height = 40;                 // 机器人 高度
        //private int step = 10;                      // 机器人 步长
        
        // test 坐标
        private int R_X = 300;                       // 机器人 初始 X坐标
        private int R_Y = 300;                       // 机器人 初始 Y坐标
        private static int _R_Width = 32;            // 机器人 宽度
        private static int _R_Height = 32;           // 机器人 高度
        private static int step = 8;                // 机器人 步长

        private float angle = 0;                    // 机器人行走的角度 初始为0 ，正方向为水平向左
        //private int angle30 = 30;
        //private int angle45 = 45;
        //private int angle60 = 60;
        //private int angle90 = 90;
        //private int angle135 = 135;
        //private int angle180 = 180;

        /// <summary>
        /// 机器人拐弯度数
        /// </summary>
        //public int[] angles = { 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180 };
        public int[] angles = { 80, 30, 40, 15 };
        //public int[] angles = { 160,120,30 };
        //=========================================================================================================================
        /* 方向设置 */ 
        private int direction = 1;                  // 默认顺时针向右  1：顺时针向右  2：顺时针向下 3：顺时针向左 4： 顺时针向上
                                                    //                5：逆时针向右  6：逆时针向下 7：逆时针向左 8： 逆时针向上  0：任意
        //=========================================================================================================================

        // 机器人沿着直线走的步数
        private int _R_LineStep = 0;
        /// <summary>
        /// 机器人 沿着直线走的步数
        /// </summary>
        public int R_LineStep
        {
            get { return _R_LineStep; }
            set { _R_LineStep = value; }
        }
        /// <summary>
        /// 机器人 沿着直线走的步数清零
        /// </summary>
        public void R_LineStepClear()
        {
            R_LineStep = 0;    
        }
        // 充电器是否找到
        private bool _chargerHasFound = false;
        public bool chargerHasFound
        {
            get { return _chargerHasFound; }
            set{ _chargerHasFound = value; }
        }
        /// <summary>
        /// 时间
        /// </summary>
        public int R_Time
        {
            get { return _R_Time; }
            set {
                // 1-1000ms范围
                if (value >= 80 && value <= 1000)
                {
                   _R_Time = value; 
                }
            }
        }
        /// <summary>
        /// 左开关
        /// </summary>
        private bool _switch_left = false;
        /// <summary>
        /// 右开关
        /// </summary>
        private bool _switch_right = false;
        /// <summary>
        /// 左开关
        /// </summary>
        public bool switch_left 
        {
            get { return _switch_left; }
            set { _switch_left = value; }
        }
        /// <summary>
        /// 右开关
        /// </summary>
        public bool switch_right
        {
            get { return _switch_right; }
            set { _switch_right = value; }
        }
        /// <summary>
        /// S型转弯后走的累计步长
        /// </summary>
        private int _SGoStep = 0;
        /// <summary>
        /// S型转弯后走的累计步长
        /// </summary>
        public int SGoStep 
        {
            get { return _SGoStep;}
            set {  _SGoStep += value; }
        }
        /// <summary>
        /// 累计步长清零初始化
        /// </summary>
        public void SGoInit()
        {
            _SGoStep = 0;
        }
        /// <summary>
        /// 是否挨着左边
        /// </summary>
        private bool _besides_left = false;
        /// <summary>
        /// 是否挨着左边
        /// </summary>
        public bool besides_left
        { 
            get{return _besides_left;}
            set { _besides_left = value;}
        }
        /// <summary>
        /// 机器人运行模式
        /// </summary>
        //private int RUN_MODE = -1;    // 默认随机    
        // For Test
        private int RUN_MODE = 4;    //  test
        /// <summary>
        /// 机器人运行模式 0-沿墙   1-左拐N°2-右拐N°
        ///                         3-S型    4-倒退
        ///                         5-沿边   6-螺旋
        ///                         7-左右交替
        ///                         -1  随机
        /// </summary>
        public int R_RUN_MODE 
        {
            get { return RUN_MODE; }
            set { RUN_MODE = value;  }
        }
        /// <summary>
        /// 返回初始 机器人X坐标
        /// </summary>
        public int Ini_R_X
        {
            get { return R_X; }
            set { R_X = value; }
        }
        /// <summary>
        /// 返回初始 机器人Y坐标
        /// </summary>
        public int Ini_R_Y
        {
            get { return R_Y; }
            set { R_Y = value; }
        }
        //可清理坐标
        private Point area_upright;
        /// <summary>
        /// 可清理区域坐标
        /// </summary>
        public Point  Area_CanClean
        {
            get { return area_upright; }
            set { area_upright = value; }
        }
        public void set_Area_CanClean_A2_(int _x)
        {
            area_upright.X = _x;
        }

        ///* 回型是否到达一周 */
        //private bool isCircle;
        //public bool IsCircle
        //{ 
        //    get { return isCircle; }
        //    set { isCircle = value; }
        //}
        public Color R_Path_Color
        {
            get { return path_color; }
            set { path_color = value; }
        }
        public Color R_Center_Color
        {
            get { return center_color; }
            set { center_color = value; }
        }
        /// <summary>
        /// 设置 机器人的八个运动方向
        /// 默认顺时针向右  1：顺时针向右  2：顺时针向下 3：顺时针向左 4： 顺时针向上
        ///                5：逆时针向右  6：逆时针向下 7：逆时针向左 8： 逆时针向上  0：任意
        /// </summary>
        /// <param name="dir">方向值</param>
        public void set_direction(int dir)
        {
            direction = dir;
        }
        /// <summary>
        /// 获取 机器人的运动方向
        /// </summary>
        /// <returns></returns>
        public int get_direction()
        {
            return direction;
        }
        /// <summary>
        /// 设置 机器人的X和Y方向的运动分量
        /// </summary>
        /// <param name="_X">X分量</param>
        /// <param name="_Y">Y分量</param>
        public void set_R_X_Y(double _X, double _Y)
        {
            set_R_X( (int)_X );
            set_R_Y( (int)_Y );
        }
        /// <summary>
        /// 返回 机器人步长
        /// </summary>
        /// <returns></returns>
        public int get_step()
        {
            return step;
        }
        //=============
        /// <summary>
        /// 设置 机器人X坐标(按照自定义步长)
        /// </summary>
        /// <param name="x">X 步长</param>
        public void set_R_X(int _X)
        {
            R_X += _X;
        }
        /// <summary>
        /// 设置 机器人Y坐标(按照自定义步长)
        /// </summary>
        /// <param name="y">Y 步长</param>
        public void set_R_Y(int _Y)
        {
            R_Y += _Y;
        }
        //=============
        /// <summary>
        /// 设置 机器人X坐标(按照默认步长)
        /// </summary>
        /// <param name="x">X 步长</param>
        public void set_R_X()
        {
            R_X += step; 
        }
        /// <summary>
        /// 设置 机器人Y坐标(按照默认步长)
        /// </summary>
        /// <param name="y">Y 步长</param>
        public void set_R_Y()
        {
            R_Y += step;
        }
        /// <summary>
        /// 返回 机器人X坐标
        /// </summary>
        /// <returns></returns>
        public int get_R_X()
        {
            return R_X;
        }
        /// <summary>
        /// 返回 机器人Y坐标
        /// </summary>
        /// <returns></returns>
        public int get_R_Y()
        {
            return R_Y;
        }
        /// <summary>
        /// 返回 机器人宽度
        /// </summary>
        /// <returns></returns>
        public int R_Width
        {
            get{return _R_Width;}
            set { _R_Width = value; }
        }
        //public int R_Width;
        /// <summary>
        /// 返回 机器人高度
        /// </summary>
        /// <returns></returns>
        public int R_Height
        {
            get { return _R_Height; }
            set { _R_Height = value; }
        }

        /* The below
         * Date: Sep 18th,2013 15:41 
         * by:   EndlessRain
         */
        /// <summary>
        /// 返回半径
        /// </summary>
        /// <returns></returns>
        private int get_radius()
        {
            return R_Width / 2;
        }
        /// <summary>
        /// 返回圆心坐标
        /// </summary>
        /// <returns>圆心坐标</returns>
        public Point get_Center_X_Y()
        {
            return new Point(R_X + R_Width / 2, R_Y + R_Height / 2);
        }
        /// <summary>
        /// 机器人通过X Y分量行走
        /// </summary>
        /// <param name="x">x分量</param>
        /// <param name="y">y分量</param>
        /// <param name="k">斜率</param>
        public void robotGoByXY(int x,int y,float k)
        {
            set_R_X(x);
            set_R_Y(y);
        }
        /// <summary>
        /// 机器人通过角度分量 行走
        /// </summary>
        /// <param name="f"></param>
        public void robotGoByAngle(double degrees)
        {
            // degrees - 90 是因为要校正正方向为水平向左
            // Sep 20,2013 10:06
            // EndlessRain
            double angle = Math.PI * (degrees - 90.0) / 180;
            set_R_X_Y(step * (double)Math.Sin(angle),step * (double)Math.Cos(angle));

            //calculateAngle(new Point(R_X, R_Y),
            //               new Point((int)(step * (double)Math.Sin(angle)),
            //                         (int)(step * (double)Math.Cos(angle))));
            //MessageBox.Show((step * (float)Math.Sin(angle)).ToString());
            // Debug Sep 18 2013 18:24
            //MessageBox.Show(Math.Cos(angle).ToString());

            // 机器人行走的步数自增1 Sep 29,2013 16:05 EndlessRain
            R_LineStep++;
        }
        /// <summary>
        /// 机器人通过角度分量 找充电座
        /// </summary>
        /// <param name="f"></param>
        public void robotGoByAngleForCharger(double degrees)
        {
            // degrees - 90 是因为要校正正方向为水平向左
            // Sep 20,2013 10:06
            // EndlessRain
            double angle = Math.PI * (degrees) / 180.0;
            set_R_X_Y(step * (double)Math.Sin(angle), step * (double)Math.Cos(angle));

            

            //MessageBox.Show((step * (float)Math.Sin(angle)).ToString());
            // Debug Sep 18 2013 18:24
            //MessageBox.Show(Math.Cos(angle).ToString());
        }
        /// <summary>
        /// 设置机器人行进角度，增量方式
        /// </summary>
        /// <param name="_angle"></param>
        public void setAngle(float _angle)
        {
            angle += _angle;
        }
        /// <summary>
        /// 设置机器人行进角度，绝对值方式
        /// </summary>
        /// <param name="_angle"></param>
        public void setAbsAngle(float _angle)
        {
            angle = _angle;
        }
        /// <summary>
        /// 返回机器人行进角度
        /// </summary>
        /// <returns></returns>
        public float Angle
        {
            get 
            {
                while (angle < 0)
                {
                    angle += 360;
                }
                while (angle > 360)
                {
                    angle -= 360;
                }
                return angle; 
            }
            set { angle = value; }
        }
        /// <summary>
        /// 计算机器人行进角度
        /// </summary>
        /// <returns></returns>
        public float calculateAngle(Point _p1, Point _p2)
        {
            
            if (_p1.X == _p2.X)
            {
                //Angle = 90;
                return 0.0f;
            }
            else
            {
                float radians = (float)Math.Atan2(_p2.Y - _p1.Y,_p2.X - _p1.X);
                Angle = (float)(radians * (180 / Math.PI));
                return radians;
            }
            //if (_p1.Y == _p2.Y && _p2.X > _p1.X)
            //{
            //    Angle = 180;
            //}
        }
        /// <summary>
        /// 机器人找充电座
        /// </summary>
        /// <param name="r"></param>
        /// <param name="c"></param>
        public void findCharger(Robot r, Charger c)
        {
            // 如果距离小于直径的十分之一
            if (r.IsLess1_10(r,c))
            {
                // 充电座已经找到
                r.chargerHasFound = true;
            }
            if (r.get_R_X() > c.C_X && r.get_R_Y() > c.C_Y)
            {
                r.robotGoByAngleForCharger(CompareRobotCharger(r, c)*180/Math.PI + 180);
                //MessageBox.Show(CompareRobotCharger(r,c).ToString());
            }
            if (r.get_R_X() < c.C_X && r.get_R_Y() < c.C_Y)
            {
                r.robotGoByAngle(CompareRobotCharger(r, c) * 180 / Math.PI);
            }
            if (r.get_R_X() > c.C_X && r.get_R_Y() < c.C_Y)
            {
                r.robotGoByAngle(CompareRobotCharger(r, c) * 180 / Math.PI);
            }
            if (r.get_R_X() < c.C_X && r.get_R_Y() > c.C_Y)
            {
                r.robotGoByAngle(CompareRobotCharger(r, c) * 180 / Math.PI + 180);
            }
            if (r.get_R_X() == c.C_X && r.get_R_Y() > c.C_Y)
            {
                r.robotGoByAngle(CompareRobotCharger(r, c) * 180 / Math.PI + 180);
            }
            if (r.get_R_X() == c.C_X && r.get_R_Y() < c.C_Y)
            {
                r.robotGoByAngle(CompareRobotCharger(r, c) * 180 / Math.PI + 180);
            }
            if (r.get_R_X() > c.C_X && r.get_R_Y() == c.C_Y)
            {
                r.robotGoByAngle(CompareRobotCharger(r, c) * 180 / Math.PI + 180);
            }
            if (r.get_R_X() < c.C_X && r.get_R_Y() == c.C_Y)
            {
                r.robotGoByAngle(CompareRobotCharger(r, c) * 180 / Math.PI + 180);
            }
        }
        /// <summary>
        /// 比较Robot和Charger，返回角度
        /// </summary>
        /// <param name="r"></param>
        /// <param name="c"></param>
        /// <returns></returns>
        private double CompareRobotCharger(Robot r, Charger c)
        {
            // 以下注释两句不可取 因为会取整，走出来的不是直线而是折线
            // Sep 20,2013 09:20
            // EndlessRain
            //int delta_x = r.get_R_X() - c.C_X;
            //int delta_y = r.get_R_Y() - c.C_Y;
            float delta_x = r.get_R_X() - c.C_X;
            float delta_y = r.get_R_Y() - c.C_Y;
            //return Math.Atan(delta_x / delta_y);
            return Math.Atan2(delta_y, delta_x);
        }
        /// <summary>
        /// 是否小于等于直径
        /// </summary>
        /// <param name="_p1">点1</param>
        /// <param name="_p2">点2</param>
        /// <returns></returns>
        private bool IsLessDiameter(Robot r, Charger c)
        {
            int delta_x = r.get_R_X() - c.C_X;
            int delta_y = r.get_R_Y() - c.C_Y;
            if (delta_x * delta_x + delta_y * delta_y <= r.R_Width * r.R_Width )
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 距离是否小于等于直径的1/10
        /// </summary>
        /// <param name="_p1">点1</param>
        /// <param name="_p2">点2</param>
        /// <returns></returns>
        private bool IsLess1_10(Robot r, Charger c)
        {
            int delta_x = r.get_R_X() - c.C_X;
            int delta_y = r.get_R_Y() - c.C_Y;
            if (delta_x * delta_x + delta_y * delta_y <= r.R_Width * r.R_Width / 100)
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 画机器人路线轨迹
        /// </summary>
        public void drawRobot(Robot r, Panel panel1)
        {
            try
            {
                using (Graphics g = panel1.CreateGraphics())
                {
                    // 画传感器
                    drawTransducer(r, panel1);
                    // 画机器人
                    g.FillEllipse(new SolidBrush(r.R_Path_Color),
                                         r.get_R_X(), r.get_R_Y(),
                                         r.R_Width, r.R_Height);
                    // 画机器人中间的圆 (为了标识机器人走到哪里了)
                    g.FillEllipse(new SolidBrush(r.R_Center_Color),
                                         r.get_R_X() + r.R_Width / 3, r.get_R_Y() + r.R_Height / 3,
                                         r.R_Width / 3, r.R_Height / 3);
                    // 保存背景图片
                    saveAsBmp(panel1);
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("绘制机器人出错："+ e.Message +" 详情:{0}",e.ToString());
            }
        }
        /// <summary>
        /// XY 初始化
        /// </summary>
        public void init_XY()
        {
            this.R_X = this.Ini_R_X;
            this.R_Y = this.Ini_R_Y;
        }
        /// <summary>
        /// 初始化传感器
        /// </summary>
        public void initTranducer()
        {
            for (int i = 0; i < t.Length; i++)
            {
                t[i] = new Transducer(get_Center_X_Y(),
                    transducerDistance,transducerAngles[i]);
            }
        }
        /// <summary>
        /// 画传感器
        /// </summary>
        private void drawTransducer(Robot r,Panel p)
        {
            for (int i = 0; i < t.Length; i++)
            {
                // 逐个画
                t[i].drawTransducer(r, p, transducerAngles[i]);
            }
        }
        /// <summary>
        /// Robot 构造函数
        /// </summary>
        public Robot()
        {
            // 初始化 传感器
            initTranducer();
            // 初始化 清扫分析类
            initAnalyze();
        }

        /// <summary>
        /// 保存背景图片
        /// </summary>
        /// <param name="p"></param>
        private void saveAsBmp(Panel p)
        {
            try
            {
                ////设置图像的大小
                //Bitmap _bitMap = new Bitmap(p.Width, p.Height);
                //Graphics g = Graphics.FromImage(_bitMap);
                ////从指定的区域中复制图形
                //g.CopyFromScreen(p.Location.X, p.Location.Y, 0, 0, new Size(p.Width, p.Height));
                ////把图形放在PictureBox中显示
                //p.BackgroundImage = _bitMap;
                //g.Dispose();
                //不能使用Dispose，不然图片就没有了，同时也会引起异常
                //_bitMap.Dispose();


                //Bitmap bit = new Bitmap(p.Width, p.Height);//实例化一个和窗体一样大的bitmap 
                //Graphics g = Graphics.FromImage(bit);
                //g.CompositingQuality = CompositingQuality.HighQuality;//质量设为最高 
                //g.CopyFromScreen(p.Left, p.Top, 0, 0, new Size(p.Width, p.Height));//保存panelSimulation区域为图片 
                ////g.CopyFromScreen(p.PointToScreen(Point.Empty), Point.Empty, p.Size);//只保存某个控件（这里是panelSimulation）
                //bit.Save(@"E:\123.bmp");//默认保存格式为PNG，保存成jpg格式质量不是很好
            }
            catch (Exception ex)
            {
                MessageBox.Show("保存图片出错：{0}",ex.ToString());
            }
        }
        /// <summary>
        /// 初始化清扫类对象
        /// </summary>
        public void initAnalyze()
        {
            // 防止重复初始化
            if (Analyze == null)
            {
                Analyze = new CleanAnalyze();
                // Debug Sep 29
                // MessageBox.Show("初始化 清扫分析类对象");
                // 初始化头结点
                Analyze.AddNode(0,0,0,0);
            }
        }
    }
}
